#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>

bool encrypt(unsigned char *buff, uint32_t key, size_t bufsize)
{
    uint32_t *p = NULL;
    size_t i = 0;
    for(i = 0;i < bufsize; i += 4){
        p = (uint32_t *)(buff + i);
        *p = *p ^ key;
    }
    return true;
}

unsigned int encrypt_file(char *fname, uint32_t key, size_t bufsize, 
                          size_t skip, size_t step, unsigned int max)
{
    size_t filesize = 0;
    size_t pos = 0;
    size_t len = 0;
    FILE *fd = fopen(fname, "r+");
    if(!fd){
        fprintf(stderr, "open file [%s] error: %s (%d)\n", strerror(errno), errno);
        return 0;
    }
    fseek(fd, 0L, SEEK_END);
    filesize = ftell(fd);
    fprintf(stdout, "file size %u\n", filesize);
    unsigned char *buff = malloc(bufsize);
    for(pos = skip; pos < filesize; pos += step){
        if(fseek(fd, pos, SEEK_SET)){
            fprintf(stderr, "fseek %u error\n");
            fclose(fd);
            free(buff);
            return pos;
        }
        len = fread(buff, 1, bufsize, fd);
        if(len != bufsize){
            fprintf(stderr, "bufsize=%u, len=%u\n", bufsize, len);
            break;
        }
        encrypt(buff, key, bufsize);
        fseek(fd, pos, SEEK_SET);
        len = fwrite(buff, 1, bufsize, fd);
        if(len != bufsize){
            fprintf(stderr, "bufsize=%u, len=%u\n", bufsize, len);
            break;
        }
    }
    free(buff);
    fclose(fd);
    return pos;
}

int main(int argc, char *argv[], char *envp[])
{
    unsigned char key[4] = {0xC3, 0xAD, 0x52, 0x70};
    size_t skip = 512;
    size_t step = 4096;
    size_t bufsize = sizeof(uint32_t) * 1;
    unsigned int max = 0;
    if(argc < 2){
        fprintf(stderr, "encrypt: missing arguments\n");
        fprintf(stderr, "try encrypt <filename>\n");
        return 1;
    }
    unsigned count =  encrypt_file(argv[1], *((uint32_t *)key), bufsize, skip, step, max);
    if(count == 0){
        return 1;
    }
    fprintf(stdout, "encrypted %u point!\n", count);
}

